#include "stdafx.h"
#include "controls_form.h"
#include "about_form.h"

#include <fstream>

#include "../../components/capture_image/src/capture_manager.h"
#include "../../components/image_view/src/image_view_manager.h"

const std::wstring ControlForm::kClassName = L"Controls";

ControlForm::ControlForm()
{
}


ControlForm::~ControlForm()
{
	if (m_pSubMenu)
	{
		m_pSubMenu->Close();
		m_pSubMenu = nullptr;
	}
}

std::wstring ControlForm::GetSkinFolder()
{
	return L"examples/controls";
}

std::wstring ControlForm::GetSkinFile()
{
	return L"controls.xml";
}

std::wstring ControlForm::GetWindowClassName() const
{
	return kClassName;
}

ui::Control* ControlForm::CreateControl(const std::wstring& pstrClass)
{
	ui::Control* control = nullptr;
	return control;
}

void ControlForm::InitWindow()
{
	ui::Button *btn_blue = static_cast<ui::Button*>(FindControl(L"btn_blue"));
	btn_blue->AttachClick([this](ui::EventArgs* args) {
#if TEST_CAPTURE_IAMGE
		CaptureManager::GetInstance()->StartCapture(nullptr);
#endif
		return true;
	});

	ui::Button *btn_white = static_cast<ui::Button*>(FindControl(L"btn_white"));
	btn_white->AttachClick([this](ui::EventArgs* args) {
#if TEST_CAPTURE_IAMGE
		ImageViewManager::GetInstance()->StartViewPic(shared::filepath::GetAppDir() + L"image_view_text.png", L"1", true);

		ImageViewManager::ImageViewInfoList imageList;
		ImageViewManager::ImageViewInfo info;
		info.id_ = L"1";
		info.path_ = shared::filepath::GetAppDir() + L"image_view_text.png";
		imageList.push_back(info);

		info.path_ = shared::filepath::GetAppDir() + L"image_view_text2.png";
		info.id_ = L"2";
		imageList.push_back(info);
		ImageViewManager::GetInstance()->SetImageViewList(imageList, L"1");
#endif
		return true;
	});

	ui::Button* btn_red = static_cast<ui::Button*>(FindControl(L"btn_red"));
	btn_red->AttachClick([this](ui::EventArgs* args) {
		std::wstring sMsg = L"MsgBox";
		ui_comp::ShowMsgBox(GetHWND(), sMsg);
		return true;
		});

	/* Initialize ListBox data */
	ui::ListBox* list = static_cast<ui::ListBox*>(FindControl(L"list"));
	for (auto i = 0; i < 30; i++)
	{
		ui::ListContainerElement* element = new ui::ListContainerElement;
		element->SetText(nbase::StringPrintf(L"ListElement %d", i));
		element->SetClass(L"listitem");
		element->SetFixedHeight(20);
		list->Add(element);
	}

	/* Initialize TreeView data */
	ui::TreeView* tree = static_cast<ui::TreeView*>(FindControl(L"tree"));
	ui::TreeNode* parent_node = nullptr;
	for (auto j = 0; j < 8; j++)
	{
		ui::TreeNode* node = new ui::TreeNode;
		node->SetClass(L"listitem");
		node->SetFixedHeight(20);
		if (parent_node)
		{
			node->SetText(nbase::StringPrintf(L"Child node %d", j));
			node->SetMargin({ 10, 0, 0, 0 });
			parent_node->AddChildNode(node);
		}
		else
		{
			node->SetText(nbase::StringPrintf(L"Parent node", j));
			tree->GetRootNode()->AddChildNode(node);
			parent_node = node;
		}
	}

	/* Initialize ComboBox data */
	ui::Combo* combo = static_cast<ui::Combo*>(FindControl(L"combo"));
	for (auto i = 0; i < 10; i++)
	{
		ui::ListContainerElement* element = new ui::ListContainerElement;
		element->SetClass(L"listitem");
		element->SetFixedHeight(30);
		element->SetBkColor(L"white");
		element->SetTextPadding({ 6,0,6,0 });
		element->SetText(nbase::StringPrintf(L"Combo element %d", i));
		combo->Add(element);
	}

	ui::MutilCombo* mutil_combo = static_cast<ui::MutilCombo*>(FindControl(L"mutil_combo"));
	ui::FilterCombo* filter_combo = static_cast<ui::FilterCombo*>(FindControl(L"filter_combo"));
	char buf[16] = {};
	for (auto i = 0; i < 100; i++)
	{
		std::string str = "item" + std::to_string(i);
		filter_combo->InsertItem(str, nbase::UTF8ToUTF16(str));
		mutil_combo->InsertItem(str, nbase::UTF8ToUTF16(str));
	}

	//ui::TreeCombo* tree_combo = static_cast<ui::TreeCombo*>(FindControl(L"tree_combo"));
	//ui::TreeNode *pRoot = tree_combo->GetTreeRootNode();
	//if (pRoot)
	//{
	//	for (int i = 0; i < 5; i++)
	//	{
	//		ui::TreeNode *pLv1 = new ui::TreeNode;
	//		pLv1->SetClass(L"listitem");
	//		pLv1->SetFixedWidth(DUI_LENGTH_STRETCH);
	//		pLv1->SetFixedHeight(24);
	//		pLv1->SetText(L"LV1");
	//		pLv1->SetUTF8DataID("LV1");

	//		pLv1->SetTextPadding({ 20, 2, 2, 0 });
	//		pLv1->SetTextStyle(DT_LEFT | DT_VCENTER);
	//		/*std::wstring image_normal = nbase::StringPrintf(L"file='../public/checkbox/check_no.png' dest='%d,4,%d,20'", 2, 18);
	//		std::wstring image_select = nbase::StringPrintf(L"file='../public/checkbox/check_yes.png' dest='%d,4,%d,20'", 2, 18);

	//		pLv1->SetStateImage(ui::kControlStateNormal, image_normal);
	//		pLv1->SetSelectedStateImage(ui::kControlStateNormal, image_select);*/

	//		pRoot->AddChildNode(pLv1);
	//		for (int j = 0; j < 1; j++)
	//		{
	//			ui::TreeNode *pLv2 = new ui::TreeNode;
	//			pLv2->SetClass(L"listitem");
	//			pLv2->SetFixedWidth(DUI_LENGTH_STRETCH);
	//			pLv2->SetFixedHeight(24);
	//			pLv2->SetText(L"LV2");
	//			pLv2->SetUTF8DataID("LV2");

	//			pLv2->SetTextPadding({ 20, 2, 2, 0 });
	//			pLv2->SetTextStyle(DT_LEFT | DT_VCENTER);
	//			/*std::wstring image_normal = nbase::StringPrintf(L"file='../public/checkbox/check_no.png' dest='%d,4,%d,20'", 2, 18);
	//			std::wstring image_select = nbase::StringPrintf(L"file='../public/checkbox/check_yes.png' dest='%d,4,%d,20'", 2, 18);

	//			pLv2->SetStateImage(ui::kControlStateNormal, image_normal);
	//			pLv2->SetSelectedStateImage(ui::kControlStateNormal, image_select);*/

	//			pLv1->AddChildNode(pLv2);
	//		}
	//	}
	//}

	/* Load xml file content in global misc thread, and post update RichEdit task to UI thread */
	nbase::ThreadManager::PostTask(shared::kThreadGlobalMisc, nbase::Bind(&ControlForm::LoadRichEditData, this));

	/* Post repeat task to update progress value 200 milliseconds once */
	/* Using ToWeakCallback to protect closure when if [ControlForm] was destoryed */
	nbase::ThreadManager::PostRepeatedTask(shared::kThreadGlobalMisc, ToWeakCallback([this](){
		nbase::TimeDelta time_delta = nbase::TimeDelta::FromMicroseconds(nbase::Time::Now().ToInternalValue());
		nbase::ThreadManager::PostTask(shared::kThreadUI, nbase::Bind(&ControlForm::OnProgressValueChagned, this, time_delta.ToMilliseconds() % 100));
	}), nbase::TimeDelta::FromMilliseconds(200));

	/* Show settings menu */
	ui::Button* settings = static_cast<ui::Button*>(FindControl(L"settings"));
	settings->AttachClick([this](ui::EventArgs* args) {
		ui::UiPoint point = args->ptMouse;
		::ClientToScreen(m_hWnd, &point);

#if 1
		if (!m_pSubMenu){
			m_pSubMenu = ui::CreateMenu(L"examples/controls/menu/settings_menu.xml");

			/* Sub menu example */
			ui::MenuElement* menu_fourth = static_cast<ui::MenuElement*>(m_pSubMenu->FindControl(L"fourth"));
			ui::MenuElement* menu_item = new ui::MenuElement;
			menu_item->SetText(L"Dynamically created");
			menu_item->SetName(L"Dynamically_Menu");
			menu_item->SetClass(L"menu_element");
			menu_item->SetFixedWidth(180);
			menu_item->SetFont(L"system_14");
			menu_item->SetTextPadding({ 20, 0, 20, 0 });
			menu_fourth->AddSubMenuItem(menu_item);
			//menu_fourth->AddTempItem(menu_item);

			ui::MenuElement* menu_third = static_cast<ui::MenuElement*>(m_pSubMenu->FindControl(L"third"));
			menu_item = new ui::MenuElement;
			menu_item->SetText(L"Dynamically created3");
			menu_item->SetName(L"Dynamically_Menu3");
			menu_item->SetClass(L"menu_element");
			menu_item->SetFixedWidth(180);
			menu_item->SetFont(L"system_14");
			menu_item->SetTextPadding({ 20, 0, 20, 0 });
			menu_third->AddSubMenuItem(menu_item);
			//menu_third->AddTempItem(menu_item);
		}
			
		m_pSubMenu->Show(point);

		/* About menu */
		ui::MenuElement* menu_about = static_cast<ui::MenuElement*>(m_pSubMenu->FindControl(L"about"));
		menu_about->DetachEvent(ui::kEventClick);
		menu_about->AttachClick([this](ui::EventArgs* args) {
			AboutForm *about_form = (AboutForm*)(ui_comp::WindowsManager::GetInstance()->GetWindow(AboutForm::kClassName, AboutForm::kClassName));
			if (!about_form)
			{
				about_form = new AboutForm();
				about_form->Create(GetHWND(), AboutForm::kClassName, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, 0);
				about_form->CenterWindow();
				about_form->ShowWindow();
			}
			else
			{
				about_form->ActiveWindow();
			}
			return true;
		});
#else
		ui::MenuWnd* sub_menu = ui::ShowMenu(L"examples/controls/menu/settings_menu.xml", point);

		/* Sub menu example */
		ui::MenuElement* menu_fourth = static_cast<ui::MenuElement*>(sub_menu->FindControl(L"fourth"));
		ui::MenuElement* menu_item = new ui::MenuElement;
		menu_item->SetText(L"Dynamically created");
		menu_item->SetName(L"Dynamically_Menu");
		menu_item->SetClass(L"menu_element");
		menu_item->SetFixedWidth(180);
		menu_item->SetFont(L"system_14");
		menu_item->SetTextPadding({ 20, 0, 20, 0 });
		menu_fourth->AddSubMenuItem(menu_item);
		//menu_fourth->AddTempItem(menu_item);

		ui::MenuElement* menu_third = static_cast<ui::MenuElement*>(sub_menu->FindControl(L"third"));
		menu_item = new ui::MenuElement;
		menu_item->SetText(L"Dynamically created3");
		menu_item->SetName(L"Dynamically_Menu3");
		menu_item->SetClass(L"menu_element");
		menu_item->SetFixedWidth(180);
		menu_item->SetFont(L"system_14");
		menu_item->SetTextPadding({ 20, 0, 20, 0 });
		menu_third->AddSubMenuItem(menu_item);
		//menu_third->AddTempItem(menu_item);

		/* About menu */
		ui::MenuElement* menu_about = static_cast<ui::MenuElement*>(sub_menu->FindControl(L"about"));
		menu_about->AttachClick([this](ui::EventArgs* args) {
			AboutForm *about_form = (AboutForm*)(ui_comp::WindowsManager::GetInstance()->GetWindow(AboutForm::kClassName, AboutForm::kClassName));
			if (!about_form)
			{
				about_form = new AboutForm();
				about_form->Create(GetHWND(), AboutForm::kClassName, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, 0);
				about_form->CenterWindow();
				about_form->ShowWindow();
			}
			else
			{
				about_form->ActiveWindow();
			}
			return true;
		});
#endif
		return true;
	});
}

LRESULT ControlForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	PostQuitMessage(0L);
	return __super::OnClose(uMsg, wParam, lParam, bHandled);
}

void ControlForm::LoadRichEditData()
{
	std::streamoff length = 0;
	std::string xml;
	//std::wstring controls_xml = ui::GlobalManager::GetResourcePath() + GetWindowResourcePath() + GetSkinFile();
	std::wstring controls_xml = shared::filepath::GetAppDir() + L"1.html";

	std::ifstream ifs(controls_xml.c_str());
	if (ifs.is_open())
	{
		ifs.seekg(0, std::ios_base::end);
		length = ifs.tellg();
		ifs.seekg(0, std::ios_base::beg);

		xml.resize(static_cast<unsigned int>(length)+1);
		ifs.read(&xml[0], length);

		ifs.close();
	}
	std::wstring sXml = nbase::UTF8ToUTF16(xml);
	// Post task to UI thread
	nbase::ThreadManager::PostTask(shared::kThreadUI, nbase::Bind(&ControlForm::OnResourceFileLoaded, this, sXml));
}

void ControlForm::OnResourceFileLoaded(const std::wstring& xml)
{
	if (xml.empty())
		return;

	auto control_edit = static_cast<ui::RichEdit*>(FindControl(L"edit"));
	if (control_edit)
	{
		control_edit->SetText(xml);
		control_edit->SetFocus();
		control_edit->HomeUp();
	}

	// Show about form
	//ui_comp::WindowsManager::SingletonShow<AboutForm>(AboutForm::kClassName);
}

void ControlForm::OnProgressValueChagned(float value)
{
	auto progress = static_cast<ui::Progress*>(FindControl(L"progress"));
	if (progress)
		progress->SetValue(value);

	auto circleprogress = static_cast<ui::Progress*>(FindControl(L"circleprogress"));
	if (circleprogress)
	{
		circleprogress->SetValue(value);
		circleprogress->SetText(nbase::StringPrintf(L"%.0f%%", value));
	}
}
